<?php
/**
 * @link https://ym2.cleverstone.top
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace builder\uploads;

use Yii;
use yii\db\Query;
use yii\di\Instance;
use yii\db\Connection;
use yii\base\Component;
use builder\helper\T;
use builder\helper\Url;

/**
 * 文件上传
 * @author cleverstone
 * @property-read Query $query Query实例
 * @property-read string $error 错误信息
 * @property-read array $result 返回结果
 * @since ym2.0
 */
class Upload extends Component
{
    /**
     * @var string 文件管理表格
     */
    public $fileTable = '{{%files}}';
    /**
     * @var string 文件分类表格
     */
    public $fileClassifyTable = '{{%files_classify}}';
    /**
     * @var Connection|string|array DB实例
     */
    public $db = 'db';
    /**
     * @var LocalProvider|string|array 文件上传驱动
     */
    public $provider = 'builder\\uploads\\LocalProvider';

    /**
     * @var string 错误信息
     */
    private $_error;
    /**
     * @var array 返回数据
     */
    private $_result = [];

    /**
     * 初始化
     * @throws \yii\base\InvalidConfigException
     */
    public function init()
    {
        $this->db = Instance::ensure($this->db, Connection::class);
        $this->provider = Instance::ensure($this->provider, BaseProvider::class);
    }

    /**
     * 新增文件
     * @param int $classify 文件分类ID
     * @param boolean $deleteTempFile 是否删除临时文件
     * @return bool
     * @throws \Throwable
     */
    public function add($classify = 0, $deleteTempFile = false)
    {
        $provider = $this->provider;
        if ($provider->move($deleteTempFile)) {
            $data = $provider->result;
            $data['classify_id'] = $classify;
            $data['created_at'] = T::now();
            $data['updated_at'] = T::now();

            try {
                $this->insertData($data);
                return true;
            } catch (\Exception $e) {
                $filePath = Yii::getAlias('@webroot' . $data['link']);
                if (is_file($filePath)) {
                    @unlink($filePath);
                }

                $this->_error = $e->getMessage();
                return false;
            }
        } else {
            $this->_error = $provider->error;
            return false;
        }
    }

    /**
     * 写入数据
     * @param array $data
     * @return bool
     * @throws \yii\db\Exception
     */
    protected function insertData(array $data)
    {
        $this->db->createCommand()->insert($this->fileTable, $data)->execute();
        $tableSchema = $this->db->getTableSchema($this->fileTable);
        $id = $this->db->getLastInsertID($tableSchema->sequenceName);
        $this->_result = ['id' => $id, 'path' => $data['link'], 'link' => Url::whole($data['link'])];

        return true;
    }

    /**
     * 获取Db Query实例
     * @return Query
     */
    public function getQuery()
    {
        return new Query();
    }

    /**
     * @return string
     */
    public function getError()
    {
        return $this->_error;
    }

    /**
     * @param string $error
     * @return $this
     */
    public function setError($error)
    {
        $this->_error = $error;
        return $this;
    }

    /**
     * @return array
     */
    public function getResult()
    {
        return $this->_result;
    }

    /**
     * @param array $result
     * @return $this
     */
    public function setResult(array $result)
    {
        $this->_result = $result;
        return $this;
    }
}